import trinity
import log
import blue

class VisualizationBase(object):
    displayName = 'Base Visualization, do not use'

    def __init__(self):
        self.originalStepStates = []



    def SetStepAttr(self, rj, stepKey, attr, value):
        if rj.HasStep(stepKey):
            self.originalStepStates.append((stepKey,
             attr,
             getattr(rj.GetStep(stepKey), attr)))
            rj.SetStepAttr(stepKey, attr, value)



    def RestoreStepStates(self, rj):
        for (step, attr, state,) in self.originalStepStates:
            rj.SetStepAttr(step, attr, state)





class VisualizerStepBase(VisualizationBase):
    displayName = 'VisualizerStepBase'
    visualizationMode = trinity.Tr2InteriorVisualizerMethod.VM_NONE

    def __init__(self):
        VisualizationBase.__init__(self)
        self.renderJobs = []
        self.wireframeModeEnabled = False



    def ApplyVisualization(self, rj):
        self.renderJobs.append(rj)
        rj.AddStep('SET_VISUALIZATION', trinity.TriStepSetVisualizationMode(rj.GetScene(), self.visualizationMode))
        self.SetStepAttr(rj, 'RENDER_SSAO', 'enabled', False)



    def RemoveVisualization(self, rj):
        rj.RemoveStep('SET_VISUALIZATION')
        self.SetEnableWireframeMode(False)
        if rj.GetScene():
            rj.GetScene().visualizeMethod = 0
        self.RestoreStepStates(rj)
        self.renderJobs.remove(rj)



    def SetEnableWireframeMode(self, enable):
        self.wireframeModeEnabled = enable
        if self.wireframeModeEnabled:
            for eachRenderJob in self.renderJobs:
                eachRenderJob.AddStep('ENABLE_WIREFRAME', trinity.TriStepEnableWireframeMode(True))
                eachRenderJob.AddStep('RESTORE_WIREFRAME', trinity.TriStepEnableWireframeMode(False))

        else:
            for eachRenderJob in self.renderJobs:
                eachRenderJob.RemoveStep('ENABLE_WIREFRAME')
                eachRenderJob.RemoveStep('RESTORE_WIREFRAME')





class DisableVisualization(VisualizerStepBase):
    displayName = 'Disable visualizations'
    visualizationMode = trinity.Tr2InteriorVisualizerMethod.VM_NONE


class WhiteVisualization(VisualizerStepBase):
    displayName = 'White'
    visualizationMode = trinity.Tr2InteriorVisualizerMethod.VM_WHITE


class ObjectNormalVisualization(VisualizerStepBase):
    displayName = 'Object Normal'
    visualizationMode = trinity.Tr2InteriorVisualizerMethod.VM_OBJECT_NORMAL


class ShadedObjectNormalVisualization(VisualizerStepBase):
    displayName = 'Shaded Object Normal'
    visualizationMode = trinity.Tr2InteriorVisualizerMethod.VM_SHADED_OBJECT_NORMAL


class TangentVisualization(VisualizerStepBase):
    displayName = 'Tangent'
    visualizationMode = trinity.Tr2InteriorVisualizerMethod.VM_TANGENT


class BiTangentVisualization(VisualizerStepBase):
    displayName = 'BiTangent'
    visualizationMode = trinity.Tr2InteriorVisualizerMethod.VM_BITANGENT


class TexCoord0Visualization(VisualizerStepBase):
    displayName = 'TexCoord0'
    visualizationMode = trinity.Tr2InteriorVisualizerMethod.VM_TEXCOORD0


class TexCoord1Visualization(VisualizerStepBase):
    displayName = 'TexCoord1'
    visualizationMode = trinity.Tr2InteriorVisualizerMethod.VM_TEXCOORD1


class TexelDensityVisualization(VisualizerStepBase):
    displayName = 'Texel Density'
    visualizationMode = trinity.Tr2InteriorVisualizerMethod.VM_TEXELDENSITY0


class NormalMapVisualization(VisualizerStepBase):
    displayName = 'Normal Map Only'
    visualizationMode = trinity.Tr2InteriorVisualizerMethod.VM_NORMALMAP


class NormalMapWorldVisualization(VisualizerStepBase):
    displayName = 'World Normal Map'
    visualizationMode = trinity.Tr2InteriorVisualizerMethod.VM_NORMALMAP_WORLD


class NormalMapUnpackedVisualization(VisualizerStepBase):
    displayName = 'Unpacked Normal Map'
    visualizationMode = trinity.Tr2InteriorVisualizerMethod.VM_NORMALMAP_UNPACKED


class NormalMapRedInvertedVisualization(VisualizerStepBase):
    displayName = 'Normal Map with Red Inverted'
    visualizationMode = trinity.Tr2InteriorVisualizerMethod.VM_NORMALMAP_RED_INVERTED


class NormalMapGreenInvertedVisualization(VisualizerStepBase):
    displayName = 'Normal Map with Green Inverted'
    visualizationMode = trinity.Tr2InteriorVisualizerMethod.VM_NORMALMAP_GREEN_INVERTED


class NormalMapBothInvertedVisualization(VisualizerStepBase):
    displayName = 'Normal Map with Both Inverted'
    visualizationMode = trinity.Tr2InteriorVisualizerMethod.VM_NORMALMAP_BOTH_INVERTED


class ShadedNormalMapVisualization(VisualizerStepBase):
    displayName = 'Shaded Normal Map Only'
    visualizationMode = trinity.Tr2InteriorVisualizerMethod.VM_SHADED_NORMALMAP


class ShadedNormalMapUnpackedVisualization(VisualizerStepBase):
    displayName = 'Unpacked Shaded Normal Map'
    visualizationMode = trinity.Tr2InteriorVisualizerMethod.VM_SHADED_NORMALMAP_UNPACKED


class ShadedNormalMapRedInvertedVisualization(VisualizerStepBase):
    displayName = 'Shaded Normal Map with Red Inverted'
    visualizationMode = trinity.Tr2InteriorVisualizerMethod.VM_SHADED_NORMALMAP_RED_INVERTED


class ShadedNormalMapGreenInvertedVisualization(VisualizerStepBase):
    displayName = 'Shaded Normal Map with Green Inverted'
    visualizationMode = trinity.Tr2InteriorVisualizerMethod.VM_SHADED_NORMALMAP_GREEN_INVERTED


class ShadedNormalMapBothInvertedVisualization(VisualizerStepBase):
    displayName = 'Shaded Normal Map with Both Inverted'
    visualizationMode = trinity.Tr2InteriorVisualizerMethod.VM_SHADED_NORMALMAP_BOTH_INVERTED


class DiffuseMapVisualization(VisualizerStepBase):
    displayName = 'Diffuse Map'
    visualizationMode = trinity.Tr2InteriorVisualizerMethod.VM_DIFFUSEMAP


class GlowMapVisualization(VisualizerStepBase):
    displayName = 'Glow Map'
    visualizationMode = trinity.Tr2InteriorVisualizerMethod.VM_GLOWMAP


class GlowMapUnpackedVisualization(VisualizerStepBase):
    displayName = 'Glow Map Unpacked'
    visualizationMode = trinity.Tr2InteriorVisualizerMethod.VM_GLOWMAP_UNPACKED


class SpecularMapVisualization(VisualizerStepBase):
    displayName = 'Specular Map'
    visualizationMode = trinity.Tr2InteriorVisualizerMethod.VM_SPECULARMAP


class SpecularMapUnpackedVisualization(VisualizerStepBase):
    displayName = 'Specular Map Unpacked'
    visualizationMode = trinity.Tr2InteriorVisualizerMethod.VM_SPECULARMAP_UNPACKED


class ReflectionMapVisualization(VisualizerStepBase):
    displayName = 'Reflection Map'
    visualizationMode = trinity.Tr2InteriorVisualizerMethod.VM_REFLECTIONMAP


class AOMapVisualization(VisualizerStepBase):
    displayName = 'AO Map'
    visualizationMode = trinity.Tr2InteriorVisualizerMethod.VM_AOMAP


class ShadowOnlyVisualization(VisualizerStepBase):
    displayName = 'Shadow Only'
    visualizationMode = trinity.Tr2InteriorVisualizerMethod.VM_SHADOW_ONLY


class OverdrawVisualization(VisualizerStepBase):
    displayName = 'Overdraw'
    visualizationMode = trinity.Tr2InteriorVisualizerMethod.VM_OVERDRAW


class EnlightenOnlyVisualization(VisualizerStepBase):
    displayName = 'Enlighten Lighting Only'
    visualizationMode = trinity.Tr2InteriorVisualizerMethod.VM_EN_ONLY


class EnlightenTargetDetailVisualization(VisualizerStepBase):
    displayName = 'Enlighten Target/Detail'
    visualizationMode = trinity.Tr2InteriorVisualizerMethod.VM_EN_TARGET_DETAIL


class EnlightenOutputDensityVisualization(VisualizerStepBase):
    displayName = 'Enlighten Output Density'
    visualizationMode = trinity.Tr2InteriorVisualizerMethod.VM_EN_OUTPUT_DENSITY


class EnlightenAlbedoVisualization(VisualizerStepBase):
    displayName = 'Enlighten Albedo'
    visualizationMode = trinity.Tr2InteriorVisualizerMethod.VM_EN_ALBEDO


class EnlightenObjectTexcoordVisualization(VisualizerStepBase):
    displayName = 'Enlighten Object Texcoords'
    visualizationMode = trinity.Tr2InteriorVisualizerMethod.VM_EN_OBJECT_TEXCOORD


class EnlightenNaughtyPixelsVisualization(VisualizerStepBase):
    displayName = 'Enlighten Naughty Pixels'
    visualizationMode = trinity.Tr2InteriorVisualizerMethod.VM_EN_NAUGHTY_PIXELS


class EnlightenDetailChartsVisualization(VisualizerStepBase):
    displayName = 'Enlighten Detail Mesh Charts'
    visualizationMode = trinity.Tr2InteriorVisualizerMethod.VM_EN_CHARTS


class EnlightenTargetChartsVisualization(VisualizerStepBase):
    displayName = 'Enlighten Target Mesh Charts'
    visualizationMode = trinity.Tr2InteriorVisualizerMethod.VM_EN_TARGET_CHARTS


class DepthVisualization(VisualizerStepBase):
    displayName = 'Depth'
    visualizationMode = trinity.Tr2InteriorVisualizerMethod.VM_DEPTH


class PrePassLightNormalVisualization(VisualizerStepBase):
    displayName = 'PrePass Lighting Normal'
    visualizationMode = trinity.Tr2InteriorVisualizerMethod.VM_LIGHT_PRE_PASS_NORMALS


class PrePassLightDepthVisualization(VisualizerStepBase):
    displayName = 'PrePass Lighting Depth'
    visualizationMode = trinity.Tr2InteriorVisualizerMethod.VM_LIGHT_PRE_PASS_DEPTH


class PrePassLightWorldPositionVisualization(VisualizerStepBase):
    displayName = 'PrePass Lighting World Position'
    visualizationMode = trinity.Tr2InteriorVisualizerMethod.VM_LIGHT_PRE_PASS_WORLD_POSITION


class PrePassLightingOnlyVisualization(VisualizerStepBase):
    displayName = 'PrePass Lighting Only'
    visualizationMode = trinity.Tr2InteriorVisualizerMethod.VM_LIGHT_PRE_PASS_LIGHTING


class PrePassLightOverdrawVisualization(VisualizerStepBase):
    displayName = 'Light Overdraw'
    visualizationMode = trinity.Tr2InteriorVisualizerMethod.VM_LIGHT_PRE_PASS_LIGHT_OVERDRAW


class LightVolumeVisualizationBase(VisualizationBase):
    displayName = 'Light Volumes'
    lightDebugRenderType = trinity.Tr2InteriorLightDebugRenderMode.DI_SHADOW_RESOLUTION

    def __init__(self):
        VisualizationBase.__init__(self)
        self.lightStates = []



    def ShouldLightBeVisualized(self, light):
        return True



    def ApplyVisualization(self, rj):
        scene = rj.GetScene()
        if (scene is not None):
            for light in scene.lights:
                if self.ShouldLightBeVisualized(light):
                    self.lightStates.append((blue.BluePythonWeakRef(light),
                     light.renderDebugInfo,
                     light.renderDebugType))
                    light.renderDebugInfo = True
                    light.renderDebugType = self.lightDebugRenderType




    def RemoveVisualization(self, rj):
        self.RestoreStepStates(rj)
        for (lightWR, rDI, rDT,) in self.lightStates:
            light = lightWR.object
            if (light is not None):
                light.renderDebugInfo = rDI
                light.renderDebugType = rDT





class LightVolumeColorBaseVisualization(LightVolumeVisualizationBase):
    displayName = 'Light Volume base'

    def ShouldLightBeVisualized(self, light):
        return True




class LightVolumeWhiteVisualization(LightVolumeColorBaseVisualization):
    displayName = 'Light Volumes (White)'
    lightDebugRenderType = trinity.Tr2InteriorLightDebugRenderMode.DI_WHITE_VOLUMES


class LightVolumeNormalVisualization(LightVolumeColorBaseVisualization):
    displayName = 'Light Volumes (Source)'
    lightDebugRenderType = trinity.Tr2InteriorLightDebugRenderMode.DI_LIGHT_COLOR


class LightVolumeShadowResolutionVisualization(LightVolumeColorBaseVisualization):
    displayName = 'Light Volumes (Shadow Resolution)'
    lightDebugRenderType = trinity.Tr2InteriorLightDebugRenderMode.DI_SHADOW_RESOLUTION


class LightVolumeShadowRelativeResolutionVisualization(LightVolumeColorBaseVisualization):
    displayName = 'Light Volumes (Shadow Relative Resolution)'
    lightDebugRenderType = trinity.Tr2InteriorLightDebugRenderMode.DI_SHADOW_RELATIVE_RESOLUTION


class PrimaryLightVolumeColorBaseVisualization(LightVolumeVisualizationBase):
    displayName = 'Primary Light Volume base'

    def ShouldLightBeVisualized(self, light):
        if getattr(light, 'primaryLighting', True):
            return True
        else:
            return False




class PrimaryLightVolumeWhiteVisualization(PrimaryLightVolumeColorBaseVisualization):
    displayName = 'Primary Light Volumes (White)'
    lightDebugRenderType = trinity.Tr2InteriorLightDebugRenderMode.DI_WHITE_VOLUMES


class PrimaryLightVolumeNormalVisualization(PrimaryLightVolumeColorBaseVisualization):
    displayName = 'Primary Light Volumes (Source)'
    lightDebugRenderType = trinity.Tr2InteriorLightDebugRenderMode.DI_LIGHT_COLOR


class PrimaryLightVolumeShadowResolutionVisualization(PrimaryLightVolumeColorBaseVisualization):
    displayName = 'Primary Light Volumes (Shadow Resolution)'
    lightDebugRenderType = trinity.Tr2InteriorLightDebugRenderMode.DI_SHADOW_RESOLUTION


class PrimaryLightVolumeShadowRelativeResolutionVisualization(PrimaryLightVolumeColorBaseVisualization):
    displayName = 'Primary Light Volumes (Shadow Relative Resolution)'
    lightDebugRenderType = trinity.Tr2InteriorLightDebugRenderMode.DI_SHADOW_RELATIVE_RESOLUTION


class SecondaryLightVolumeColorBaseVisualization(LightVolumeVisualizationBase):
    displayName = 'Secondary Light Volume base'

    def ShouldLightBeVisualized(self, light):
        if getattr(light, 'secondaryLighting', True):
            return True
        else:
            return False




class SecondaryLightVolumeWhiteVisualization(SecondaryLightVolumeColorBaseVisualization):
    displayName = 'Secondary Light Volumes (White)'
    lightDebugRenderType = trinity.Tr2InteriorLightDebugRenderMode.DI_WHITE_VOLUMES


class SecondaryLightVolumeNormalVisualization(SecondaryLightVolumeColorBaseVisualization):
    displayName = 'Secondary Light Volumes (Source)'
    lightDebugRenderType = trinity.Tr2InteriorLightDebugRenderMode.DI_LIGHT_COLOR


class SecondaryLightVolumeShadowResolutionVisualization(SecondaryLightVolumeColorBaseVisualization):
    displayName = 'Secondary Light Volumes (Shadow Resolution)'
    lightDebugRenderType = trinity.Tr2InteriorLightDebugRenderMode.DI_SHADOW_RESOLUTION


class SecondaryLightVolumeShadowRelativeResolutionVisualization(SecondaryLightVolumeColorBaseVisualization):
    displayName = 'Secondary Light Volumes (Shadow Relative Resolution)'
    lightDebugRenderType = trinity.Tr2InteriorLightDebugRenderMode.DI_SHADOW_RELATIVE_RESOLUTION


class ShadowcastingLightVolumeColorBaseVisualization(LightVolumeVisualizationBase):
    displayName = 'Shadowcasting Light Volume base'

    def ShouldLightBeVisualized(self, light):
        if getattr(light, 'shadowCasterTypes', True):
            return True
        else:
            return False




class ShadowcastingLightVolumeWhiteVisualization(ShadowcastingLightVolumeColorBaseVisualization):
    displayName = 'Shadowcasting Light Volumes (White)'
    lightDebugRenderType = trinity.Tr2InteriorLightDebugRenderMode.DI_WHITE_VOLUMES


class ShadowcastingLightVolumeNormalVisualization(ShadowcastingLightVolumeColorBaseVisualization):
    displayName = 'Shadowcasting Light Volumes (Source)'
    lightDebugRenderType = trinity.Tr2InteriorLightDebugRenderMode.DI_LIGHT_COLOR


class ShadowcastingLightVolumeShadowResolutionVisualization(ShadowcastingLightVolumeColorBaseVisualization):
    displayName = 'Shadowcasting Light Volumes (Shadow Resolution)'
    lightDebugRenderType = trinity.Tr2InteriorLightDebugRenderMode.DI_SHADOW_RESOLUTION


class ShadowcastingLightVolumeShadowRelativeResolutionVisualization(ShadowcastingLightVolumeColorBaseVisualization):
    displayName = 'Shadowcasting Light Volumes (Shadow Relative Resolution)'
    lightDebugRenderType = trinity.Tr2InteriorLightDebugRenderMode.DI_SHADOW_RELATIVE_RESOLUTION


class TransparentLightVolumeColorBaseVisualization(LightVolumeVisualizationBase):
    displayName = 'Transparent Light Volume base'

    def ShouldLightBeVisualized(self, light):
        if getattr(light, 'affectTransparentObjects', True):
            return True
        else:
            return False




class TransparentLightVolumeWhiteVisualization(TransparentLightVolumeColorBaseVisualization):
    displayName = 'Transparent Light Volumes (White)'
    lightDebugRenderType = trinity.Tr2InteriorLightDebugRenderMode.DI_WHITE_VOLUMES


class TransparentLightVolumeNormalVisualization(TransparentLightVolumeColorBaseVisualization):
    displayName = 'Transparent Light Volumes (Source)'
    lightDebugRenderType = trinity.Tr2InteriorLightDebugRenderMode.DI_LIGHT_COLOR


class TransparentLightVolumeShadowResolutionVisualization(TransparentLightVolumeColorBaseVisualization):
    displayName = 'Transparent Light Volumes (Shadow Resolution)'
    lightDebugRenderType = trinity.Tr2InteriorLightDebugRenderMode.DI_SHADOW_RESOLUTION


class TransparentLightVolumeShadowRelativeResolutionVisualization(TransparentLightVolumeColorBaseVisualization):
    displayName = 'Transparent Light Volumes (Shadow Relative Resolution)'
    lightDebugRenderType = trinity.Tr2InteriorLightDebugRenderMode.DI_SHADOW_RELATIVE_RESOLUTION


